package ve.usb.crm;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

import ve.usb.cohesion.runtime.CohesionAction;

import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import ve.usb.cohesion.runtime.HibernateUtil;
import ve.usb.crm.hibernate.*;

import ve.usb.cohesion.runtime.Pair;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.ArrayList;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * 
 */
public class AccionesCuenta extends CohesionAction {

    /**
     * Called by Struts for the execution of action APreCuentas.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward APreCuentas(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"VCuentas",};
        final int SALIDA_0 = 0;

        int salida = SALIDA_0;
//Checking for actors administrador, empleado
        if (!CohesionActor.checkActor(request, 5)) {
            return mapping.findForward(CohesionActor.SALIDA_ACTOR);
        }
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {
            //Deberia cambiar el tipo de muestreo de
            String tmp = (String) request.getAttribute("tipoMuestra");

            List<Cuenta> list = new ArrayList<Cuenta>();
            if (CohesionActor.checkActor(request, CohesionActor.ACTOR_administrador)) {
                list = (List<Cuenta>) s.createQuery("from Cuenta where esactivo = true").list();
            } else if (CohesionActor.checkActor(request, CohesionActor.ACTOR_empleado)) {
                Personal usuario = (Personal) request.getSession().getAttribute("Usuario");

                list = (List<Cuenta>) s.createQuery("from Cuenta where"
                        + " respCuenta = :usuario and esactivo = true").setLong("usuario", usuario.getIdPersonal()).list();
            }

            request.setAttribute("L_Cuenta", list);

            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    /**
     * Called by Struts for the execution of action APreCrearCuenta.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward APreCrearCuenta(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"VCrearCuenta",};
        final int SALIDA_0 = 0;

        int salida = SALIDA_0;
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {

//Genero el formulario y cargo los collection
            FCrearCuenta fFCrearCuenta = FCrearCuenta.clear(mapping, request);
            cargarCollection(fFCrearCuenta, s);

            //Se trata de obtener el atributo idCuenta y obtengo el atributo usuario actual en la session
            Personal usuario = (Personal) request.getSession().getAttribute("Usuario");

            //Se verifica si ahi un usuario en la sesión para agregarlo al formulario
            if (usuario != null) {
                fFCrearCuenta.setRespCuenta(usuario.getIdPersonal());
            }
            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    /**
     * Called by Struts for the execution of action ACrearCuenta.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward ACrearCuenta(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"APreCuenta", "VCrearCuenta",};
        final int SALIDA_0 = 0;
        final int SALIDA_1 = 1;

        int salida = SALIDA_0;
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {
            FCrearCuenta fFCrearCuenta = (FCrearCuenta) form;
            //Genero las instancias de cuenta personal y categoria
            Cuenta cuenta = new Cuenta();
            Personal responsable;
            Categoria tipoSector;
            boolean hayError = false;

            //Se Verifica si el formulario tiene un nombre válido
            if (fFCrearCuenta.getNombre().compareTo("") == 0) {
                hayError = true;
                request.setAttribute("nombreError", "<span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span> Debe introducir un nombre v&aacute;lido");
            }

            //Verifico si escogio algun tipo
            if (fFCrearCuenta.getTipo() == 0l) {
                hayError = true;
                request.setAttribute("tipoError", "<span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span> Debe seleccionar un tipo v&aacute;lido");
            }

            //Se verifica si se escogio un responsable de cuentas
            if (fFCrearCuenta.getRespCuenta() == 0l) {
                hayError = true;
                request.setAttribute("respCuentaError", "<span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span> Debe seleccionar un responsable de la cuenta v&aacute;lido");
            }

            //Se Verifica si el formulario tiene un nombre de un páis válido
            if (fFCrearCuenta.getPais().compareTo("") == 0) {
                hayError = true;
                request.setAttribute("paisError", "<span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span> Debe introducir un p&aacute;is v&aacute;lido");
            }

            //Verifico si escogio algun sector
            if (fFCrearCuenta.getSector() == 0l) {
                hayError = true;
                request.setAttribute("sectorError", "<span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span> Debe seleccionar un sector v&aacute;lido");
            }

            //Se Verifica si el formulario tiene un número de empleados válido
            if (fFCrearCuenta.getNumeroEmpleado() < 0) {
                hayError = true;
                request.setAttribute("numeroEmpleadoError", "<span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span> Debe introducir un n&uacute;mero de empleado v&aacute;lido");
            }

            //Se Verifica si el formulario tiene un nombre de un páis válido
            if (fFCrearCuenta.getIngresosAnuales() < 0.0) {
                hayError = true;
                request.setAttribute("ingresosAnualesError", "<span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span> Debe introducir un n&uacute;mero v&aacute;lido");
            }

            if (hayError) {
                cargarCollection(fFCrearCuenta, s);
                salida = SALIDA_1;
            } else {
                //Se llena la instancia de cuenta con los atributos del formulario
                cuenta.setNombre(fFCrearCuenta.getNombre());
                cuenta.setCiudad(fFCrearCuenta.getCiudad());
                cuenta.setCodigoPostal(fFCrearCuenta.getCodigoPostal());
                cuenta.setComentarios(fFCrearCuenta.getComentarios());
                cuenta.setCorreoE(fFCrearCuenta.getCorreoE());
                cuenta.setDescripcion(fFCrearCuenta.getDescripcion());
                cuenta.setDireccion(fFCrearCuenta.getDireccion());
                cuenta.setDireccionFacturacion(fFCrearCuenta.getDireccionFacturacion());
                cuenta.setEstado(fFCrearCuenta.getEstado());
                cuenta.setIngresosAnuales(fFCrearCuenta.getIngresosAnuales());
                cuenta.setNumeroEmpleado(fFCrearCuenta.getNumeroEmpleado());
                cuenta.setPaginaWeb(fFCrearCuenta.getPaginaWeb());
                cuenta.setPais(fFCrearCuenta.getPais());
                cuenta.setTelefonoFax(fFCrearCuenta.getTelefonoFax());
                cuenta.setTelefonoOficina(fFCrearCuenta.getTelefonoOficina());
                cuenta.setEsActivo(true);


                tipoSector = (Categoria) s.load(Categoria.class, fFCrearCuenta.getTipo());
                cuenta.setTipo(tipoSector);

                responsable = (Personal) s.load(Personal.class, fFCrearCuenta.getRespCuenta());
                cuenta.setRespCuenta(responsable);

                tipoSector = (Categoria) s.load(Categoria.class, fFCrearCuenta.getSector());
                cuenta.setSector(tipoSector);

                if (fFCrearCuenta.getIdCuenta() == 0) {
                    s.save(cuenta);
                } else {
                    cuenta.setIdCuenta(fFCrearCuenta.getIdCuenta());
                    s.update(cuenta);
                }
                s.flush();

                salida = SALIDA_0;
                request.setAttribute("idCuenta", cuenta.getIdCuenta());
            }

            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    /**
     * Called by Struts for the execution of action APreCuenta.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward APreCuenta(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"VCuenta",};
        final int SALIDA_0 = 0;

        int salida = SALIDA_0;
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {

            //Obtengo el id de la cuenta del request asi este como atributo o como parametro
            Long idCuenta = (Long) request.getAttribute("idCuenta");
            if (idCuenta == null) {
                idCuenta = lookup_Long(request, "idCuenta");
            }

            //se sacan la cuenta de la base de dato
            Cuenta cuenta = (Cuenta) s.createQuery("from Cuenta where idCuenta = :idCuenta").setLong("idCuenta", idCuenta).uniqueResult();

            //se inicializan los datos necesarios
            Hibernate.initialize(cuenta.getRespCuenta());
            Hibernate.initialize(cuenta.getTipo());
            Hibernate.initialize(cuenta.getSector());

            List<Contacto> listaCliente = (List<Contacto>) s.createQuery("from Contacto where cuenta = :idCuenta and esActivo = true").setLong("idCuenta", cuenta.getIdCuenta()).list();

            for (Iterator<Contacto> it = listaCliente.iterator(); it.hasNext();) {
                Contacto contacto = it.next();
                Hibernate.initialize(contacto);

            }

            //Iniciliazo todas las oportunidaes
            List<Oportunidad> listaOportunidad = (List<Oportunidad>) s.createQuery("from Oportunidad where cuenta = :idCuenta and esActivo = true").setLong("idCuenta", cuenta.getIdCuenta()).list();

            for (Iterator<Oportunidad> it = listaOportunidad.iterator(); it.hasNext();) {
                Oportunidad oportunidad = it.next();
                Hibernate.initialize(oportunidad.getNombre());
                Hibernate.initialize(oportunidad.getEtapa());
                Hibernate.initialize(oportunidad.getFechaCierre());
            }


            //Iniciliazo todas las oportunidaes
            List<Proyecto> listaProyecto = (List<Proyecto>) s.createQuery("from Proyecto where cuenta = :idCuenta and esActivo = true").setLong("idCuenta", cuenta.getIdCuenta()).list();

            for (Iterator<Proyecto> it = listaProyecto.iterator(); it.hasNext();) {
                Proyecto proyecto = it.next();
                Hibernate.initialize(proyecto);
                
            }


            //Iniciliazo todas las tareas relacionadas
            List<Tarea> listaTarea = (List<Tarea>) s.createQuery("from Tarea "
                    + "where cuentaRelacionada = :idCuenta and esActivo = true").setLong("idCuenta", cuenta.getIdCuenta()).list();

            for (Iterator<Tarea> it = listaTarea.iterator(); it.hasNext();) {
                Tarea tarea = it.next();
                Hibernate.initialize(tarea.getPersonal());
                Hibernate.initialize(tarea.getAsunto());
                Hibernate.initialize(tarea.getEstado());
                Hibernate.initialize(tarea.getContactoRelacionado());


            }

            //agrego en el request los atributos
            request.setAttribute("L_Proyecto", listaProyecto);
            request.setAttribute("L_Oportunidad", listaOportunidad);
            request.setAttribute("L_Cliente", listaCliente);
            request.setAttribute("L_Tarea", listaTarea);
            request.setAttribute("Cuenta", cuenta);

            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    /**
     * Called by Struts for the execution of action APreModificarCuenta.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward APreEditarCuenta(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"VModificarCuenta",};
        final int SALIDA_0 = 0;

        int salida = SALIDA_0;
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {

//Saco el Id de la cuenta del request
            Long idCuenta = Long.valueOf((String) request.getParameter("idCuenta")).longValue();

            //Consigo la cuenta en la base de datos
            Cuenta cuenta = (Cuenta) s.createQuery("from Cuenta where idCuenta = :idCuenta").setLong("idCuenta", idCuenta).uniqueResult();

            //Creo el formulario y lo lleno
            FCrearCuenta fFCrearCuenta = FCrearCuenta.clear(mapping, request);

            fFCrearCuenta.setCiudad(cuenta.getCiudad());
            fFCrearCuenta.setCodigoPostal(cuenta.getCodigoPostal());
            fFCrearCuenta.setComentarios(cuenta.getComentarios());
            fFCrearCuenta.setCorreoE(cuenta.getCorreoE());
            fFCrearCuenta.setDescripcion(cuenta.getDescripcion());
            fFCrearCuenta.setDireccion(cuenta.getDireccion());
            fFCrearCuenta.setDireccionFacturacion(cuenta.getDireccionFacturacion());
            fFCrearCuenta.setEstado(cuenta.getEstado());
            fFCrearCuenta.setIngresosAnuales(cuenta.getIngresosAnuales());
            fFCrearCuenta.setNombre(cuenta.getNombre());
            fFCrearCuenta.setNumeroEmpleado(cuenta.getNumeroEmpleado());
            fFCrearCuenta.setPaginaWeb(cuenta.getPaginaWeb());
            fFCrearCuenta.setPais(cuenta.getPais());
            fFCrearCuenta.setTelefonoFax(cuenta.getTelefonoFax());
            fFCrearCuenta.setTelefonoOficina(cuenta.getTelefonoOficina());
            fFCrearCuenta.setIdCuenta(cuenta.getIdCuenta());
            fFCrearCuenta.setRespCuenta(cuenta.getRespCuenta().getIdPersonal());
            fFCrearCuenta.setTipo(cuenta.getTipo().getIdCategoria());
            fFCrearCuenta.setSector(cuenta.getSector().getIdCategoria());
            cargarCollection(fFCrearCuenta, s);

            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    /**
     * Called by Struts for the execution of action AEliminarCuenta.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward AEliminarCuenta(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"APreCuentas", "APreCuenta",};
        final int SALIDA_0 = 0;
        final int SALIDA_1 = 1;

        int salida = SALIDA_0;
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {

            //Consigo el id de la cuenta
            Long idCuenta = lookup_Long(request, "idCuenta");
            Cuenta cuenta = (Cuenta) s.load(Cuenta.class, idCuenta);

            List<Oportunidad> oportunidad = (List<Oportunidad>) s.createQuery("from Oportunidad where cuenta = :resp").setLong("resp", idCuenta).list();
            for (Oportunidad t : oportunidad) {
                t.setEsActivo(false);
                s.update(t);
                s.flush();
                List<Tarea> tarea = (List<Tarea>) s.createQuery("from Tarea where oportunidadrelacionada = :resp").setLong("resp", t.getIdOportunidad()).list();
                for (Tarea tar : tarea) {
                    tar.setEsActivo(false);
                    s.update(tar);
                    s.flush();
                }
            }

            List<Proyecto> proyecto = (List<Proyecto>) s.createQuery("from Proyecto where cuenta = :resp").setLong("resp", idCuenta).list();
            for (Proyecto t : proyecto) {
                t.setEsActivo(false);
                s.update(t);
                s.flush();
            }

            List<Tarea> tarea = (List<Tarea>) s.createQuery("from Tarea where cuentarelacionada = :resp").setLong("resp", idCuenta).list();
            for (Tarea t : tarea) {
                t.setEsActivo(false);
                s.update(t);
                s.flush();
            }

            // lo borro y verifico que lo alla borrado
            cuenta.setEsActivo(false);
            s.update(cuenta);
            s.flush();

            try {
                s.flush();
            } catch (Exception ex1) {
                ex1.printStackTrace();
                //salida = SALIDA_1;
                request.setAttribute("msg", "No se pudo eliminar entidad.");
            }

            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try {
                s.close();
            } catch (Exception ex2) {
            }
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    private void cargarCollection(FCrearCuenta fFCrearCuenta, Session s) {

        Long tipoCategoria = (Long) s.createQuery("select idCategoria from Categoria where nombre = 'tipoCuenta' and tipo = :root").setLong("root", 0l).uniqueResult();
        Long sectionCategoria = (Long) s.createQuery("select idCategoria from Categoria where nombre = 'sector' and tipo = :root").setLong("root", 0l).uniqueResult();

        {
            List<Pair> list =
                    (List<Pair>) s.createQuery(
                    "select new ve.usb.cohesion.runtime.Pair(nombre.apellido, idPersonal) "
                    + "from Personal").list();
            list.add(0, new Pair("Ninguna", 0));
            fFCrearCuenta.setListPersonal(list);
        }

        {
            List<Pair> listTipo =
                    (List<Pair>) s.createQuery(
                    "select new ve.usb.cohesion.runtime.Pair(nombre, idCategoria) "
                    + "from Categoria where tipo= :idCategoria").setLong("idCategoria", tipoCategoria).list();
            listTipo.add(0, new ve.usb.cohesion.runtime.Pair("Ninguna", 0));
            fFCrearCuenta.setListTipoCategoria(listTipo);
        }


        {
            List<Pair> listSection =
                    (List<Pair>) s.createQuery(
                    "select new ve.usb.cohesion.runtime.Pair(nombre, idCategoria) "
                    + "from Categoria where tipo=:idCategoria").setLong("idCategoria", sectionCategoria).list();
            listSection.add(0, new ve.usb.cohesion.runtime.Pair("Ninguno", 0));
            fFCrearCuenta.setListSectorCategoria(listSection);
        }

    }
}
